package com.example.jetpacktest.coroutine

import kotlinx.coroutines.*
import org.junit.Test
import java.io.IOException
import java.lang.Exception
import java.lang.NullPointerException
import java.lang.RuntimeException

class Test005 {


    @Test
    fun test001(){
        runBlocking {
            val exHandler: CoroutineExceptionHandler = CoroutineExceptionHandler{_, ex ->
                println("ex = $ex")
            }

            val job1 = GlobalScope.launch(exHandler) {
                println("job1")
                throw RuntimeException("launch抛出的异常")
            }

            val job2 = GlobalScope.async(exHandler) {
                println("job2")
                throw RuntimeException("async抛出的异常")
            }

            /*try{
                job2.await()
            }catch (ex: Exception){
                println("$ex")
            }*/


            joinAll(job1, job2)
        }
    }


    @Test
    fun test002(){
        runBlocking {
            val exHandler = CoroutineExceptionHandler{ _, ex ->
                println("ex = $ex")
            }

            val job = GlobalScope.launch (exHandler){

                //first child
                launch {
                    try{
                        delay(Long.MAX_VALUE)
                    }finally {
                        withContext(NonCancellable){
                            println("first child finish.......start")
                            delay(3000)
                            println("first child finish.......end")
                        }
                    }
                }

                //second child
                launch {
                    println("second child throw a exception")
                    delay(10)
                    throw RuntimeException("算术异常......")
                }

            }

            job.join()

        }
    }


    @Test
    fun test003(){
        runBlocking {
            val exHandler = CoroutineExceptionHandler{ _ , ex ->
                println("$ex........${ex.suppressed.contentToString()}")
            }

            val job = GlobalScope.launch(exHandler) {
                launch {
                    delay(10)
                    println("first throw ex")
                    throw IOException("first 抛出的io异常")
                }

                launch {
                    try{
                        delay(100)
                    }finally {
                        throw NullPointerException("second抛出的空指针异常")
                    }
                }
            }
            job.join()

        }
    }



    @Test
    fun test004(){
        runBlocking {
            val supervisor = SupervisorJob()
            with(CoroutineScope(coroutineContext + supervisor)){
                val first = launch (CoroutineExceptionHandler{_, ex -> println("$ex")}){
                    delay(10)
                    println("first throw ex")
                    throw IOException()
                }

                val second = launch {
                    try{
                        delay(6000)
                        println("second正常结束")
                    }catch (ex: Exception){
                        println("ex = $ex")
                    }
                }

                first.join()
                /*delay(1000)
                cancel()*/
                second.join()
            }
        }
    }


}